import { useRouter } from "next/router";
import z from "zod";
import { AppSettings } from "@calcom/app-store/_components/AppSettings";
import { InstallAppButton } from "@calcom/app-store/components";
import { InstalledAppVariants } from "@calcom/app-store/utils";
import DisconnectIntegration from "@calcom/features/apps/components/DisconnectIntegration";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { RouterOutputs, trpc } from "@calcom/trpc/react";
import { App } from "@calcom/types/App";
import { AppGetServerSidePropsContext } from "@calcom/types/AppGetServerSideProps";
import {
Alert,
Button,
EmptyScreen,
List,
AppSkeletonLoader as SkeletonLoader,
ShellSubHeading,
} from "@calcom/ui";
import {
FiBarChart,
FiCalendar,
FiCreditCard,
FiGrid,
FiPlus,
FiShare2,
FiVideo,
} from "@calcom/ui/components/icon";
import { QueryCell } from "@lib/QueryCell";
import { CalendarListContainer } from "@components/apps/CalendarListContainer";
import IntegrationListItem from "@components/apps/IntegrationListItem";
import InstalledAppsLayout from "@components/apps/layouts/InstalledAppsLayout";
function ConnectOrDisconnectIntegrationButton(props: {
credentialIds: number[];
type: App["type"];
isGlobal?: boolean;
installed?: boolean;
invalidCredentialIds?: number[];
}) {
const { type, credentialIds, isGlobal, installed } = props;
const { t } = useLocale();
const [credentialId] = credentialIds;
const utils = trpc.useContext();
const handleOpenChange = () => {
utils.viewer.integrations.invalidate();
};
if (credentialId) {
if (type === "stripe_payment") {
return (
);
}
return (
);
}
if (!installed) {
return (
);
}
/** We don't need to "Connect", just show that it's installed */
if (isGlobal) {
return (
{t("default")}
);
}
return (
(
)}
onChanged={handleOpenChange}
/>
);
}
interface IntegrationsContainerProps {
variant?: typeof InstalledAppVariants[number];
exclude?: typeof InstalledAppVariants[number][];
}
interface IntegrationsListProps {
variant?: IntegrationsContainerProps["variant"];
data: RouterOutputs["viewer"]["integrations"];
}
const IntegrationsList = ({ data }: IntegrationsListProps) => {
return (
{data.items
.filter((item) => item.invalidCredentialIds)
.map((item) => (
0}
actions={
}>
))}
);
};
const IntegrationsContainer = ({ variant, exclude }: IntegrationsContainerProps): JSX.Element => {
const { t } = useLocale();
const query = trpc.viewer.integrations.useQuery({ variant, exclude, onlyInstalled: true });
const emptyIcon = {
calendar: FiCalendar,
conferencing: FiVideo,
automation: FiShare2,
analytics: FiBarChart,
payment: FiCreditCard,
web3: FiBarChart,
other: FiGrid,
};
return (
}
success={({ data }) => {
return (
<>
{data.items.length > 0 ? (
{t("add")}
}
/>
) : (
{t(`connect_${variant || "other"}_apps`)}
}
/>
)}
>
);
}}
/>
);
};
const querySchema = z.object({
category: z.enum(InstalledAppVariants),
});
type querySchemaType = z.infer;
export default function InstalledApps() {
const { t } = useLocale();
const router = useRouter();
const category = router.query.category as querySchemaType["category"];
const categoryList: querySchemaType["category"][] = [
"payment",
"conferencing",
"automation",
"analytics",
"web3",
];
return (
{categoryList.includes(category) && }
{category === "calendar" && }
{category === "other" && (
)}
);
}
// Server side rendering
export async function getServerSideProps(ctx: AppGetServerSidePropsContext) {
// get return-to cookie and redirect if needed
const { cookies } = ctx.req;
if (cookies && cookies["return-to"]) {
const returnTo = cookies["return-to"];
if (returnTo) {
ctx.res.setHeader("Set-Cookie", "return-to=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT");
return {
redirect: {
destination: `${returnTo}`,
permanent: false,
},
};
}
}
const params = querySchema.safeParse(ctx.params);
if (!params.success) return { notFound: true };
return {
props: {
category: params.data.category,
},
};
}